package com.sun.umbrella.service.oauth2.impl;

import com.sun.core.enums.BaseBizEnum;
import com.sun.core.enums.BaseErrorEnum;
import com.sun.core.enums.DeletedEnum;
import com.sun.core.enums.EnableEnum;
import com.sun.core.ex.BusinessCheckFailException;
import com.sun.core.ex.BusinessProcessFailException;
import com.sun.star.base.util.BeanUtil;
import com.sun.umbrella.dao.OauthClientMapper;
import com.sun.umbrella.domain.bo.OauthClientBO;
import com.sun.umbrella.domain.entity.OauthClientDO;
import com.sun.umbrella.domain.enums.EnableStateEnum;
import com.sun.umbrella.manager.utils.PasswordUtil;
import com.sun.umbrella.service.oauth2.ClientService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;

/**
 * @author Jay
 * @version v1.0
 * @description 第三方客户端接入相关的逻辑
 * @date 2017-11-24 11:21
 */
@Service
@Slf4j
public class ClientServiceImpl implements ClientService {


    @Autowired
    private OauthClientMapper oauthClientMapper;


    /**
     * 创建新的客户端
     *
     * @param clientName
     * @return
     */
    @Transactional(rollbackFor = BusinessProcessFailException.class)
    @Override
    public Boolean createClient(String clientName) {
        if (StringUtils.isEmpty(clientName)) {
            throw new BusinessCheckFailException(BaseErrorEnum.BNS_CHK_ERROR.getCode(), "clientName不能为空");
        }
        OauthClientDO oauthClientDO = new OauthClientDO();
        Date date = new Date();
        oauthClientDO.setClientId(PasswordUtil.generageMD5(UUID.randomUUID().toString()));
        oauthClientDO.setClientSecret(PasswordUtil.generageMD5(UUID.randomUUID().toString()));
        oauthClientDO.setClientName(clientName);
        oauthClientDO.setIsDeleted(DeletedEnum.NO.getKey());
        oauthClientDO.setGmtCreate(date);
        oauthClientDO.setGmtModified(date);
        oauthClientDO.setEnable(EnableEnum.YES.getKey());
        if (oauthClientMapper.insert(oauthClientDO) != BaseBizEnum.FIRST.getKey()) {
            throw new BusinessProcessFailException("创建新的客户端失败", BaseErrorEnum.SAVE_ERROR.getCode());
        }
        return Boolean.TRUE;
    }


    /**
     * 删除客户端
     *
     * @param clientId
     */
    @Transactional(rollbackFor = BusinessProcessFailException.class)
    @Override
    public void deleteClient(String clientId) {
        if (StringUtils.isEmpty(clientId)) {
            throw new BusinessCheckFailException(BaseErrorEnum.BNS_CHK_ERROR.getCode(), "clientId不能为空");
        }
        OauthClientDO oauthClientDO = oauthClientMapper.selectByClientId(clientId, null);
        if (oauthClientDO == null) {
            throw new BusinessCheckFailException(BaseErrorEnum.BNS_CHK_ERROR.getCode(), "数据异常");
        }
        OauthClientDO update = new OauthClientDO();
        update.setClientId(clientId);
        update.setIsDeleted(DeletedEnum.YES.getKey());
        if (oauthClientMapper.updateEnableAndIsDeletedByClientId(update) != BaseBizEnum.FIRST.getKey()) {
            throw new BusinessProcessFailException("操作失败", BaseErrorEnum.BNS_CHK_ERROR.getCode());
        }
    }

    /**
     * 查询所有的被授权的客户端
     *
     * @return
     */
    @Override
    public List<OauthClientBO> queryClientList() {
        List<OauthClientDO> oauthClientDOS = oauthClientMapper.selectAll();
        if (CollectionUtils.isEmpty(oauthClientDOS)) {
            return new ArrayList<>();
        }
        return BeanUtil.copyList(oauthClientDOS, OauthClientBO.class);
    }

    /**
     * 根据clientId查询记录
     *
     * @param clientId
     * @return
     */
    @Override
    public OauthClientDO findByClientId(String clientId) {
        if (StringUtils.isEmpty(clientId)) {
            throw new BusinessCheckFailException(BaseErrorEnum.BNS_CHK_ERROR.getCode(), "clientId不能为空");
        }
        return oauthClientMapper.selectByClientId(clientId, EnableEnum.YES.getKey());
    }

    /**
     * 根据clientSecret查询记录
     *
     * @param clientSecret
     * @return
     */
    @Override
    public OauthClientDO findByClientSecret(String clientSecret) {
        if (StringUtils.isEmpty(clientSecret)) {
            throw new BusinessCheckFailException(BaseErrorEnum.BNS_CHK_ERROR.getCode(), "clientSecret不能为空");
        }
        return oauthClientMapper.selectByClientSecret(clientSecret, EnableEnum.YES.getKey());
    }

    /**
     * 启用或禁用
     *
     * @param clientId
     * @param enable
     * @return
     */
    @Transactional(rollbackFor = BusinessProcessFailException.class)
    @Override
    public Boolean enableClient(String clientId, Integer enable) {
        if (StringUtils.isEmpty(clientId)) {
            throw new BusinessCheckFailException(BaseErrorEnum.BNS_CHK_ERROR.getCode(), "clientId不能为空");
        }
        if (enable == null) {
            throw new BusinessCheckFailException(BaseErrorEnum.BNS_CHK_ERROR.getCode(), "enable不能为空");
        }
        if (enable != EnableStateEnum.ROLE_NOE_ENABLE.getKey() && enable != EnableStateEnum.ROLE_ENABLE.getKey()) {
            throw new BusinessCheckFailException(BaseErrorEnum.BNS_CHK_ERROR.getCode(), "enable传入值不合法");
        }
        OauthClientDO oauthClientDO = oauthClientMapper.selectByClientId(clientId, null);
        if (oauthClientDO == null) {
            throw new BusinessCheckFailException(BaseErrorEnum.BNS_CHK_ERROR.getCode(), "数据异常");
        }
        OauthClientDO update = new OauthClientDO();
        update.setEnable(enable);
        update.setClientId(clientId);
        if (oauthClientMapper.updateEnableAndIsDeletedByClientId(update) != BaseBizEnum.FIRST.getKey()) {
            throw new BusinessProcessFailException("操作失败", BaseErrorEnum.BNS_CHK_ERROR.getCode());
        }
        return Boolean.TRUE;
    }
}
